﻿using System;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

namespace HttpHelper

{
    /// <summary>
    ///
    /// </summary>
    public class HttpResponse
    {
        private const string DoubleQuote = "\"";
        private const string Pattern = "<meta[^<]*charset=([^<]*)[\"']";
        private const string Semicolon = ";";
        private const string SingleQuote = "'";
        private Encoding encoding;

        /// <summary>
        /// 保存网页相应内容文本
        /// </summary>
        private string text;

        /// <summary>
        /// 取返回字节集
        /// </summary>
        public byte[] Body { get; set; } = Array.Empty<byte>();

        /// <summary>
        /// 指定随附的正文数据的长度（以字节为单位）
        /// </summary>
        public long ContentLength { get; set; } = 0;

        /// <summary>
        /// 获取响应的内容类型。
        /// </summary>
        public string ContentType { get; set; } = string.Empty;

        /// <summary>
        /// 获取响应的内容编码。
        /// </summary>
        public Encoding Encoding
        {
            get
            {
                if (encoding == null)
                    GetEncoding();
                return encoding;
            }
            set { encoding = value; }
        }

        /// <summary>
        /// 返回请求的头数据
        /// </summary>
        public WebHeaderCollection Headers { get; set; } = new WebHeaderCollection();

        /// <summary>
        /// 小于两百 或 大于三百的 都属于 访问不成功
        /// </summary>
        public bool IsSuccessStatus
        { get { return !(StatusCode < 200 || StatusCode > 300); } }

        /// <summary>
        /// 取得HTTP返回协议头中的302重定向地址
        /// </summary>
        public string Location
        {
            get
            {
                return GetHeader(HttpResponseHeader.Location);
            }
        }

        /// <summary>
        /// 错误描述
        /// </summary>
        public string Message { get; set; } = string.Empty;

        /// <summary>
        /// 取状态码
        /// </summary>
        public HttpStatusCode Status { get; set; } = HttpStatusCode.NotFound;

        /// <summary>
        /// 取状态码
        /// </summary>
        public int StatusCode
        { get { return (int)Status; } }

        /// <summary>
        /// 取状态文本
        /// </summary>
        public string StatusText { get; set; } = string.Empty;

        /// <summary>
        /// 取返回文本
        /// </summary>
        public string Text
        {
            get
            {
                // 文本为空 byte To String
                if (text == null)
                    text = Encoding.GetString(Body);
                return text;
            }
        }

        /// <summary>
        /// 获取请求头数据
        /// </summary>
        /// <param name="Header"></param>
        /// <returns></returns>
        public string GetHeader(string Header)
        {
            return Headers.Get(Header) ?? string.Empty;
        }

        /// <summary>
        /// 获取请求头数据
        /// </summary>
        /// <param name="Header"></param>
        /// <returns></returns>
        public string GetHeader(HttpResponseHeader Header)
        {
            return Headers[Header] ?? string.Empty;
        }

        /// <summary>
        /// 解析Htmnl 文本编码
        /// </summary>
        private void GetEncoding()
        {
            encoding = Encoding.UTF8;
            if (ContentType.StartsWith("text/html"))// 判断是否为Html 文本 只有Html 才能解析
            {
                var str = text = encoding.GetString(Body);//先以Utf-8 编码转换到字符串文本
                if (Regex.IsMatch(str, Pattern))//判断 Html字符串内是否有匹配正则表达式的字符串
                {
                    var CharSe = Regex.Match(text, Pattern).Groups[1].Value.ToLower()//取编码文本 到小写
                        .Replace(DoubleQuote, null).Replace(SingleQuote, null).Replace(Semicolon, null)//替换掉特殊字符
                        .Trim().Replace("iso-8859-1", "gbk");// 删首尾空 替换掉 特殊字符
                    if (!CharSe.StartsWith("utf-8"))//判断是否为UTF8 如为UTF8 encoding 以为UTF8 就不转换
                    {
                        try
                        {
                            encoding = Encoding.GetEncoding(CharSe);
                        }
                        catch (Exception) { }
                    }
                }
            }
        }
    }
}